using System;
using System.Runtime.Serialization.Formatters.Binary;
using SmartBoard.Core.Data;
using SmartBoard.Core.Networking.Client;
using System.IO;
using SmartBoard.Core.Server;

namespace SmartBoard.Core.Command
{
    public class StreamingContext
    {
        public event EventHandler<RemoteActionExecuteEventArgs> RemoteActionExecuted;

        public StreamingContext(IBoardElementStreamManager streamManager, IBoardElementDataManager dataManager, INetworkServiceModule networkService)
        {
            this.StreamManager = streamManager;
            this.DataManager = dataManager;
            NetworkService = networkService;
        }

        public IBoardElementStreamManager StreamManager
        {
            get; private set;
        }

        public IBoardElementDataManager DataManager
        {
            get; private set;
        }

        public INetworkServiceModule NetworkService
        {
            get; private set;
        }

        public void Write(object parameter, int messageId)
        {
            byte[] data = null;
            using (var stream = new MemoryStream())
            {
                var formatter = new BinaryFormatter();
                if (parameter != null)
                {
                    formatter.Serialize(stream, parameter);
                    data = stream.ToArray();
                }
            }
            this.NetworkService.WriteMessage(new ServerMessage(NetworkService.ModuleId, messageId, data));
        }

        internal void RaiseRemoteActionExecuted(byte[] payload)
        {
            if (this.RemoteActionExecuted != null)
            {
                object data = null;
                if (payload != null)
                {
                    using (var stream = new MemoryStream(payload))
                    {
                        var formatter = new BinaryFormatter();
                        data = formatter.Deserialize(stream);
                    }
                }
                RemoteActionExecuted(this, new RemoteActionExecuteEventArgs(data));
            }
        }
    }
}